package jmine.tec.hydra.api;

import java.io.InputStream;
import java.util.Map;

import jmine.tec.hydra.domain.HydraSystem;
import jmine.tec.hydra.domain.enumx.HydraRequestType;
import bancosys.tec.persist.dao.BeanNotFoundException;

/**
 * Provê as implementações de request, actions, specifications e messages que serão utilizadas para o processamento de requisições.
 * 
 * @author lundberg
 */
public interface HydraProvider {

    /**
     * Cria um novo request.
     * 
     * @param requestType requestType
     * @return HydraRequest
     */
    HydraRequest createRequest(HydraRequestType requestType);

    /**
     * Cria um novo request para a especificação dada.
     * 
     * @param requestType requestType
     * @param specification specification
     * @return HydraRequest
     */
    HydraRequest createRequest(HydraRequestType requestType, HydraSpecification specification);

    /**
     * Cria uma nova mensagem
     * 
     * @param request request
     * @param direction direction
     * @param body body
     * @param properties properties
     * @return HydraRequest
     */
    HydraMessage createMessage(HydraRequest request, MessageDirection direction, InputStream body, Map<String, String> properties);

    /**
     * Cria uma instância da action que corresponde à interface
     * 
     * @param <A> tipo da action
     * @param action classe da action
     * @return instância da action
     */
    <A extends HydraAction> A createAction(Class<A> action);

    /**
     * Encontra a especificação com a action dada, associada ao sistema dado. Deve trazer apenas as especificações habilitadas.
     * 
     * @param system system
     * @param action action
     * @return HydraSpecification
     * @throws BeanNotFoundException caso a especificação não seja encontrada
     */
    HydraSpecification findSpecification(HydraSystem system, String action) throws BeanNotFoundException;
}
